//
//  WYHMFIPrinterTool.m
//  BluetoothPrint
//
//  Created by wang on 2017/11/3.
//  Copyright © 2017年 wang. All rights reserved.
//

#import "WYHMFIPrinterTool.h"

@interface WYHMFIPrinterTool()<NSStreamDelegate>
@property (nonatomic, strong) EASession *session;
@property (nonatomic, strong) EAAccessory *accessory;

@property (assign) BOOL goPrint;

@property (assign) BOOL hintDismiss;

@end

@implementation WYHMFIPrinterTool

- (instancetype)init
{
    self  = [super init];
    if (self) {
       
    }
    return self;
}
// 从已经连接的外设中查找我们的设备(根据协议名称来查找) 根据uuid查找
- (void)searchOurAccessory {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (_hintDismiss == NO) {
            if ([_delegate respondsToSelector:@selector(printerErrorHint:)]) {
                _hintDismiss = YES;
                [_delegate printerErrorHint:PrintMFIErrorTypeError];
            }
        }
    });
    
    
    
    NSString *searchMacAddress = self.dataTool.printerParam.printerUUID;
    // search our device
    for (EAAccessory *accessory in [EAAccessoryManager sharedAccessoryManager].connectedAccessories) {
        
        if (searchMacAddress.length == 0) {
            if ([kSPKLightingHeadphoneProtocolString isEqualToString:[accessory.protocolStrings firstObject]] == YES) {
                self.accessory = accessory;
            }
        }else{
            NSString *macAddress = [accessory valueForKey:@"macAddress"];
            if ([macAddress isEqualToString:searchMacAddress]) {
                self.accessory = accessory;
            }
        }
        
       
        
        
        
//        if ([kSPKLightingHeadphoneProtocolString isEqualToString:[accessory.protocolStrings firstObject]] == YES) {
        
//            self.accessory = accessory;
            //创建EASession并打开输入、输出通道，类似如下代码：
//            [self openSession];
            // 硬件的协议字符串和硬件厂商提供的一致，这个就是我们要找的设备了！
            
            // log：可以打印一下该硬件的相关资讯
//            for (NSString *proStr in accessory.protocolStrings) {
//                [info appendFormat:@"protocolString = %@\n", proStr];
//            }
//            [info appendFormat:@"\n"];
//            [info appendFormat:@"manufacturer = %@\n", accessory.manufacturer];
//            [info appendFormat:@"name = %@\n", accessory.name];
//            [info appendFormat:@"modelNumber = %@\n", accessory.modelNumber];
//            [info appendFormat:@"serialNumber = %@\n", accessory.serialNumber];
//            [info appendFormat:@"firmwareRevision = %@\n", accessory.firmwareRevision];
//            [info appendFormat:@"hardwareRevision = %@\n", accessory.hardwareRevision];
//
            // Log...
//        }
    }
    
    if (self.accessory) {
        [self openSessionCount:1];
    }else{
        if ([_delegate respondsToSelector:@selector(printerErrorHint:)]) {
            _hintDismiss = YES;
            [_delegate printerErrorHint:PrintMFIErrorTypeFindError];
        }
    }
}

/**
 创建EASession并打开输入、输出通道，类似如下代码：
 */
- (BOOL)openSessionCount:(NSInteger)count {
    
    // 根据已经连接的EAAccessory对象和这个协议（反向域名字符串）来创建EASession对象，并打开输入、输出通道
    self.session = [[EASession alloc] initWithAccessory:self.accessory forProtocol: kSPKLightingHeadphoneProtocolString];
    if(self.session != nil) {
        // open input stream
        self.session.inputStream.delegate = self;
        [self.session.inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        [self.session.inputStream open];
        
        // open output stream
        self.session.outputStream.delegate = self;
        [self.session.outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        [self.session.outputStream open];
    }
    else {
        NSLog(@"Failed to create session");
        if (count > 6) {
            _hintDismiss = YES;
            if ([_delegate respondsToSelector:@selector(printerErrorHint:)]) {
                _hintDismiss = YES;
                [_delegate printerErrorHint:PrintMFIErrorTypeCreateError];
            }
        }else{
            __weak __typeof(&*self)weakSelf = self;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [weakSelf openSessionCount:count+1];
            });
        }
    }
    
    return (nil != self.session);
}
#pragma mark NSStreamDelegate
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
    NSLog(@"%ld",(unsigned long)eventCode);
    switch (eventCode) {
        case NSStreamEventNone:
            break;
        case NSStreamEventOpenCompleted:
            break;
        case NSStreamEventHasBytesAvailable:
            NSLog(@"Input stream is ready");
            // 接收到硬件数据了，根据指令定义对数据进行解析。
//            [self readFromDevice];
            break;
        case NSStreamEventHasSpaceAvailable:
            NSLog(@"Output stream is ready");

            // 可以发送数据给硬件了
//            [self writeToDevice];
            //开始拼接数据
        {
            if (self.goPrint) {
                self.goPrint = NO;
                 [self printData];
            }
        }
            break;
        case NSStreamEventErrorOccurred:
            break;
        case NSStreamEventEndEncountered:
            break;
        default:
            break;
    }
}

/**
 开始打印
 */
- (void)startToPrint
{
     self.goPrint = YES;
     [self searchOurAccessory];
}

- (void)printData
{
    
    //开始拼接数据
    [self.dataTool printAppendData];
    NSMutableData *nData = [NSMutableData data];
    for (NSData *data in self.dataTool.datas) {
        [nData appendData:data];
    }
    [self.dataTool.datas removeAllObjects];
    [self.session.outputStream write:[nData bytes] maxLength:nData.length];
    if ([_delegate respondsToSelector:@selector(printSuccess)]) {
        _hintDismiss = YES;
        [_delegate printSuccess];
    }
}
- (void)dealloc
{
    [self closeSession];
}
// close the session with the accessory.
- (void)closeSession
{
    [[_session inputStream] close];
    
    [[_session inputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    [[_session inputStream] setDelegate:nil];
    
    [[_session outputStream] close];
    
    [[_session outputStream] removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    [[_session outputStream] setDelegate:nil];

    _session = nil;
}
//outputStream的write:maxLength:方法，类似如下：
//1
//
//[self.session.outputStream write:[self.writeData bytes] maxLength:self.writeDataLen];
//
//接收数据：
//
//inputStream的read:maxLength:方法，类似如下：
//1
//
//[self.session.inputStream read:buffer maxLength:SPK_INPUT_DATA_BUFFER_LEN];
@end
